package com.streamAPI;

import com.streamAPI.entity.Person;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Stream流的特性
 *    流是lazy的,不用就不会被调用
 *    三大部分:
 *      数据流
 *      N个中间操作
 *      终止操作
 */
public class StreamAPIDemo03 {
    public static void main(String[] args) {
        /**
         * StreamAPI中间操作的各种用法
         *  1. filter  过滤:挑出我们要用的元素
         *  2. map     映射: 一对一映射,将一个元素映射为另一个元素  a变成b
         *      包含: mapToInt  mapToLong mapToDouble
         *  3. flatMap 散列: 一对多映射
         *  4. distinct 去重
         *  5. sorted 排序
         *  6. peek  将元素打印出来
         *  7. limit  限制流返回的数据
         *  8. takeWhile  当满足条件,拿到元素,当不满足条件,直接结束流
         *  9. groupingBy  对流进行分组
         *
         *  终止操作
         *  1. collect  将流转为一个集合
         *  2. foreach  将流遍历出来
         *  3. count    统计个数
         *
         *  声明式编程: 基于事件的回调
         */
        Person person1 = new Person("李 四","男",18);
        Person person2 = new Person("王 五","女",19);
        Person person3 = new Person("赵 六","男",20);

        List<Person> personLists = List.of(person1,person2,person3);

        //挑出年龄大于18岁的人
        //filter map flatMap  流里面的每一个元素都完整走完一个流水线以后,才会轮到下一个元素
        //第一个元素流经所有管道后,才会轮到下一个元素
        personLists.stream()
                .filter(person ->{
                   return  person.getAge() > 18; //挑出年龄大于18岁的人
                })
                .peek(person -> System.out.println("filter" + person))  //将元素打印出来
                .map(person -> {
                    return person.getName();  //拿到所有人的姓名
                })
                .peek(person -> System.out.println("map" + person))  //将元素打印出来
                .flatMap(val ->{
                    String[] s = val.split(" ");
                    Stream<String> stream = Arrays.stream(s);
                    return stream;   //将姓名按照空格拆分,返回新的流
                })
                .peek(person -> System.out.println("flatMap" + person))  //将元素打印出来
                .distinct()//去重
                .limit(1)  //限制返回
                .sorted(String::compareTo)  //排序
                .forEach(person -> System.out.println(person));


        //takeWhile
        List<Integer> list = List.of(1, 2, 3, 4, 5).stream()
                .filter(val -> val > 2)
                .collect(Collectors.toList());

        System.out.println(list);

        List<Integer> list1 = List.of(1, 2, 3, 4, 5).stream()
                .takeWhile(val -> val > 2)
                .collect(Collectors.toList());

        System.out.println(list1);

        //groupingBy
        List<Person> personLists3 = List.of(person1,person2,person3);
        Map<String, List<Person>> listPerson = personLists3.stream()
                .filter(person -> person.getAge() > 10)
                .collect(Collectors.groupingBy(person -> person.getGender()));

        System.out.println(listPerson);
    }
}
